﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.Text;
using scomA3proj.net.bing.api;
using System.Text.RegularExpressions;
using System.IO;
using scomA3proj.edu.asu.eas.venus;
using System.Xml;
using scomA3proj.net.virtualearth.dev;
using scomA3proj.Map;




namespace scomA3proj
{
    
    public class RequiredServices_JStanley : IRequiredServices_JStanley
    {
        #region  ---  stockDays

        public string[] stockDaysCompare(List<StockInfo> stockInfo)
        {
            StockInfo temp = null;
            DayOfWeek day;
            string[] daysCompared = new string[6];
            DayStock mon = new DayStock("Monday");
            DayStock tues = new DayStock("Tuesday");
            DayStock wed = new DayStock("Wednesday");
            DayStock thurs = new DayStock("Thursday");
            DayStock fri = new DayStock("Friday");
            DayStock weekend = new DayStock("Weekend");
            List<DayStock> daysOfTheWeek = new List<DayStock>();
            daysOfTheWeek.Add(mon);
            daysOfTheWeek.Add(tues);
            daysOfTheWeek.Add(wed);
            daysOfTheWeek.Add(thurs);
            daysOfTheWeek.Add(fri);
            daysOfTheWeek.Add(weekend);
            decimal sum = 0;
            decimal avgValue = 0;
            for (int i = 0; i < stockInfo.Count; i++)
            {
                temp = stockInfo.ElementAt(i);
                day = temp.date.DayOfWeek;
                sum += temp.price;
                switch (day)
                {
                    case DayOfWeek.Monday:
                        mon.increment(temp.price);
                        break;
                    case DayOfWeek.Tuesday:
                        tues.increment(temp.price);
                        break;
                    case DayOfWeek.Wednesday:
                        wed.increment(temp.price);
                        break;
                    case DayOfWeek.Thursday:
                        thurs.increment(temp.price);
                        break;
                    case DayOfWeek.Friday:
                        fri.increment(temp.price);
                        break;
                    default:
                        weekend.increment(temp.price);
                        break;
                }                
            }  
          
            //find avg 
            avgValue = sum / stockInfo.Count;
            foreach (DayStock listItem in daysOfTheWeek)
            {
                listItem.calcAvg();
            }
            //populate string
            for(int i = 0; i < daysOfTheWeek.Count; i++)
            {
                daysCompared[i] = daysOfTheWeek.ElementAt(i).toString(avgValue);
            }           

            return daysCompared;
        }

        #endregion

        public int compareDates(DateTime date1, DateTime date2)
        {
            int result;
            result = DateTime.Compare(date1, date2);

            if (result < 0)
            {
                //date1 is before date2
                System.TimeSpan diff1 = date1.Subtract(date2);
                if (diff1.Days >= 0)
                    return diff1.Days;
                else
                    return (diff1.Days * -1);
            }
            else if (result == 0)
            {
                //dates are equal
                return 0;
            }
            else
            {
                //date2 comes before date1
                System.TimeSpan diff1 = date2.Subtract(date1);
                if (diff1.Days >= 0)
                    return diff1.Days;
                else
                    return (diff1.Days * -1);
            }            
        }
        
        
        #region  ---  MapService

        public string[] getLocationMap(string address)
        {
            string[] myArray = new string[1];
            myArray[0] = MakeGeocodeRequest(address);
            return myArray;

        }

        public string GetImagery(string locationString)
        {
            string key = "AtnqKifBPR4QoM6mip3iWhduY3KmOkc8XvlkWGRgslFdHESldT-8s0TRs7NOeYO1";
            MapUriRequest mapUriRequest = new MapUriRequest();

            // Set credentials using a valid Bing Maps key
            mapUriRequest.Credentials = new scomA3proj.Map.Credentials();
            mapUriRequest.Credentials.ApplicationId = key;

            // Set the location of the requested image
            mapUriRequest.Center = new scomA3proj.Map.Location();
            string[] digits = locationString.Split(',');
            mapUriRequest.Center.Latitude = double.Parse(digits[0].Trim());
            mapUriRequest.Center.Longitude = double.Parse(digits[1].Trim());

            // Set the map style and zoom level
            MapUriOptions mapUriOptions = new MapUriOptions();
            mapUriOptions.Style = MapStyle.AerialWithLabels;
            mapUriOptions.ZoomLevel = 17;

            // Set the size of the requested image in pixels
            //mapUriOptions.ImageSize = new scomA3proj.Map.SizeOfint();
            //mapUriOptions.ImageSize.Height = 220;
            //mapUriOptions.ImageSize.Width = 300;

            mapUriRequest.Options = mapUriOptions;

            //Make the request and return the URI
            scomA3proj.Map.ImageryService imageryService = new scomA3proj.Map.ImageryService();
            MapUriResponse mapUriResponse = imageryService.GetMapUri(mapUriRequest);
            return mapUriResponse.Uri;
        }

        private string MakeGeocodeRequest(string address)
        {
            string Results = "";
            try
            {
                // Set a Bing Maps key before making a request
                string key = "AtnqKifBPR4QoM6mip3iWhduY3KmOkc8XvlkWGRgslFdHESldT-8s0TRs7NOeYO1";
                GeocodeService client = new GeocodeService();
                GeocodeRequest geocodeRequest = new GeocodeRequest();

                // Set the credentials using a valid Bing Maps Key
                geocodeRequest.Credentials = new scomA3proj.net.virtualearth.dev.Credentials();
                geocodeRequest.Credentials.ApplicationId = key;

                // Set the full address query
               // geocodeRequest.Query = "1 Microsoft Way, Redmond, WA";
                geocodeRequest.Query = address;

                // Set the options to only return high confidence results
                ConfidenceFilter[] filters = new ConfidenceFilter[1];
                filters[0] = new ConfidenceFilter();
                filters[0].MinimumConfidence = scomA3proj.net.virtualearth.dev.Confidence.High;

                GeocodeOptions geocodeOptions = new GeocodeOptions();
                geocodeOptions.Filters = filters;

                geocodeRequest.Options = geocodeOptions;
                
                // Make the geocode request
               // GeocodeService.GeocodeServiceClient geocodeService =
               // new GeocodeService.GeocodeServiceClient("BasicHttpBinding_IGeocodeService");
                GeocodeResponse geocodeResponse =  new GeocodeResponse();
                geocodeResponse = client.Geocode(geocodeRequest);                
                //Results = geocodeResponse.Results[0].DisplayName;
                Results = geocodeResponse.Results[0].BestView.Northeast.Latitude + " " + geocodeResponse.Results[0].BestView.Northeast.Longitude;

            }
            catch (Exception ex)
            {
                Results = "An exception occurred: " + ex.Message;

            }
            return Results;
        }
        
        #endregion        
        
               
        #region --- WsOperations ---

        public string[] getWsOperations(string url)
        {
            List<string> operationList = new List<string>();
            string[] operationArray;
            Service client = new Service();
            string web2String = null;
            StringBuilder output = new StringBuilder();
            Boolean flag = true;
            string genre = "";

            web2String = client.GetWebContent(url);

          // System.Web.Services.Description.ServiceDescription          
            
            
            
            //call service to get client
            web2String = client.GetWebContent(url);

            using (XmlReader reader = XmlReader.Create(new StringReader(web2String)))
            {
                
                try
                {
                    reader.ReadToFollowing("wsdl:binding");

                    while (flag)
                    {
                        reader.ReadToFollowing("wsdl:operation");
                        //reader.MoveToFirstAttribute();
                       // string temp = reader.Value;
                        string temp1 = reader.ReadOuterXml();
                      
                        if (!temp1.Equals(""))
                        {
                            genre =temp1;
                            //skip repeats 
                            if (operationList.Contains(genre))
                            {
                                continue;
                            }
                            else
                            {
                                operationList.Add(genre);
                            }
                        }
                        else
                        {
                            flag = false;
                        }
                        
                    }
                }
                catch(Exception e) {}
             }    

            //operationList.AddRange(regExOperations(web2String));

            operationArray = new string[operationList.Count()];
            for (int i = 0; i < operationList.Count(); i++)
            {
                operationArray[i] = operationList.ElementAt(i);
            }

            return operationArray;
        }


        public static List<string> regExOperations(string input)
        {
            List<string> l = new List<string>();

            //The regex to match wsdl urls
            //string reg = "operation name="[^"\\]*";
            Regex r = new Regex(@"""[^""\\]*(?:\\.[^""\\]*)*""");
            MatchCollection mc = r.Matches(input, 0);
            //add all matches to the list
            for (int i = 0; i < mc.Count; i++)
            {
                string res = mc[i].Value.Trim();                
                //filter out repeats
                if (l.Contains(res))
                    continue;

                l.Add(mc[i].Value.Trim());
            }
            return l;
        }

        #endregion


       
        #region --- WSdlAddress ---    

        public string[] getWsdlAddress(string url)
        {
            List<string> addressList = new List<string>();
            string[] addressArray;
            Service client = new Service();
            string web2String = null;

            //call service to get client
            web2String = client.GetWebContent(url);
            

            //stuff
            addressList.AddRange(FindWSDLUrls(web2String));

            addressArray = new string[addressList.Count()];
            for (int i = 0; i < addressList.Count(); i++)
            {
                addressArray[i] = addressList.ElementAt(i);
            }
            return addressArray;

        }

        public static List<string> FindWSDLUrls(string input)
        {
            List<string> l = new List<string>();

            //The regex to match wsdl urls
            //Regex r = new Regex(@"operation name=[a-zA-Z0-9\\.\\-_/""\\]+>");
            Regex r = new Regex(@"http(s?)://[a-zA-Z0-9\\.\\-_/]+.wsdl");
            MatchCollection mc = r.Matches(input, 0);
            //add all matches to the list
            for (int i = 0; i < mc.Count; i++)
            {
                string res = mc[i].Value.Trim();
                //Filter out the obviously invalid web services like localhost and example.com
                if (res.Contains("://localhost") || res.Contains("://127.0.0.1") || res.Contains("://example.com") || res.Contains("://www.example.com"))
                    continue;
                //filter out repeats
                if (l.Contains(res))
                    continue;

                l.Add(mc[i].Value.Trim());
            }
            return l;
        }
       

        #endregion
    }
}
